﻿using Admin.NET.Core.Service;
using EasyTest.Application.Const;
using EasyTest.Application.Service.QuestionBank.Enum;
using Microsoft.AspNetCore.Http;
using EasyTest.Application.Service.QuestionBank.Helper;
namespace EasyTest.Application.Service;

/// <summary>
/// 题目管理服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class EtQuestionService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<EtQuestion> _etQuestionRep;
    private readonly SqlSugarRepository<EtQuestionBank> _questionBankRep;
    private readonly SqlSugarRepository<EtQuestionCate> _questionCateRep;

    public EtQuestionService(SqlSugarRepository<EtQuestion> etQuestionRep, SqlSugarRepository<EtQuestionBank> questionBankRep, SqlSugarRepository<EtQuestionCate> questionCateRep)
    {
        _etQuestionRep = etQuestionRep;
        _questionBankRep = questionBankRep;
        _questionCateRep = questionCateRep;
    }

    /// <summary>
    /// 分页查询题目
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询题目")]
    public async Task<SqlSugarPagedList<EtQuestionOutput>> Page(PageEtQuestionInput input)
    {
        var query = _etQuestionRep.AsQueryable()
            .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => 
                u.Content.Contains(input.SearchKey) || 
                u.Tags.Contains(input.SearchKey))
            .WhereIF(input.Status.HasValue, u => (int)u.Status == input.Status)
            .WhereIF(input.QuestionBankId.HasValue, u => u.QuestionBankId == input.QuestionBankId)
            .WhereIF(input.CategoryId.HasValue, u => u.CategoryId == input.CategoryId)
            .WhereIF(input.Difficulty.HasValue, u => u.Difficulty == input.Difficulty)
            .Where(u => u.IsDelete == false)
            // 修改关联查询，指定字段别名
            .LeftJoin<EtQuestionBank>((q, b) => q.QuestionBankId == b.Id)
            .LeftJoin<EtQuestionCate>((q, b, c) => q.CategoryId == c.Id)
            .Select((q, b, c) => new EtQuestionOutput
            {
                Id = q.Id,  // 明确指定来源表
                Content = q.Content,
                QuestionType = q.QuestionType,
                Options = q.Options,
                Answer = q.Answer, 
                Analysis = q.Analysis,
                Difficulty = q.Difficulty,
                Score = q.Score,
                Status = (int)q.Status,
                OrderNo = q.OrderNo,
                QuestionBankId = q.QuestionBankId,
                QuestionBankName = b.Name,
                CategoryId = q.CategoryId, 
                CategoryName = c.Name
            });

        return await query.ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 构建排序
    /// </summary>
    private ISugarQueryable<EtQuestion> OrderBuilder(ISugarQueryable<EtQuestion> query, PageEtQuestionInput input)
    {
        if (!string.IsNullOrWhiteSpace(input.SortField) && !string.IsNullOrWhiteSpace(input.SortOrder))
        {
            var sortField = input.SortField.ToLower();
            var sortOrder = input.SortOrder.ToLower();

            query = sortField switch
            {
                "orderno" => sortOrder == "asc" ? query.OrderBy(u => u.OrderNo) : query.OrderBy(u => u.OrderNo, OrderByType.Desc),
                "createtime" => sortOrder == "asc" ? query.OrderBy(u => u.CreateTime) : query.OrderBy(u => u.CreateTime, OrderByType.Desc),
                "score" => sortOrder == "asc" ? query.OrderBy(u => u.Score) : query.OrderBy(u => u.Score, OrderByType.Desc),
                _ => query.OrderBy(u => u.OrderNo)
            };
        }
        return query;
    }

    /// <summary>
    /// 增加题目
    /// </summary>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加题目")]
    public async Task<long> Add(AddEtQuestionInput input)
    {
        // 1. 检查题库是否存在
        var bank = await _questionBankRep.GetFirstAsync(u => u.Id == input.QuestionBankId)
            ?? throw Oops.Oh("所选题库不存在");

        // 2. 检查分类是否存在
        var category = await _questionCateRep.GetFirstAsync(u => u.Id == input.CategoryId)
            ?? throw Oops.Oh("所选分类不存在");

        // 3. 根据题目类型验证选项和答案
        ValidateQuestionData(input);

        var entity = input.Adapt<EtQuestion>();
        await _etQuestionRep.InsertAsync(entity);
        return entity.Id;
    }

    /// <summary>
    /// 验证题目数据
    /// </summary>
    private void ValidateQuestionData(EtQuestionBaseInput input)
    {
        // 验证选项格式
        QuestionValidateHelper.ValidateOptions(input.Options, (QuestionTypeEnum)input.QuestionType);

        // 验证答案格式
        QuestionValidateHelper.ValidateAnswer(input.Answer, (QuestionTypeEnum)input.QuestionType, input.Options);

        // 验证标签格式
        QuestionValidateHelper.ValidateTags(input.Tags);

        // 验证附件格式
        QuestionValidateHelper.ValidateAttachments(input.Attachments);
    }

    /// <summary>
    /// 更新题目
    /// </summary>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新题目")]
    public async Task Update(UpdateEtQuestionInput input)
    {
        var entity = await _etQuestionRep.GetFirstAsync(u => u.Id == input.Id)
            ?? throw Oops.Oh("题目不存在");

        // 1. 检查题库是否存在
        if(input.QuestionBankId != entity.QuestionBankId)
        {
            var bank = await _questionBankRep.GetFirstAsync(u => u.Id == input.QuestionBankId)
                ?? throw Oops.Oh("所选题库不存在");
        }

        // 2. 检查分类是否存在
        if(input.CategoryId != entity.CategoryId)
        {
            var category = await _questionCateRep.GetFirstAsync(u => u.Id == input.CategoryId)
                ?? throw Oops.Oh("所选分类不存在");
        }

        // 3. 根据题目类型验证选项和答案
        ValidateQuestionData(input);

        // 4. 更新实体
        var updateEntity = input.Adapt<EtQuestion>();
        await _etQuestionRep.AsUpdateable(updateEntity).IgnoreColumns(true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 删除题目
    /// </summary>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除题目")]
    public async Task Delete(DeleteEtQuestionInput input)
    {
        // 1. 检查题目是否存在
        var entity = await _etQuestionRep.GetFirstAsync(u => u.Id == input.Id)
            ?? throw Oops.Oh("题目不存在");

        // 2. 检查题目是否可以删除
        // TODO: 根据业务需求添加检查,比如是否被试卷引用等

        // 3. 执行软删除
        await _etQuestionRep.FakeDeleteAsync(entity);
    }

    /// <summary>
    /// 获取题目详情
    /// </summary>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取题目详情")]
    public async Task<EtQuestion> Detail([FromQuery] QueryByIdEtQuestionInput input)
    {
        return await _etQuestionRep.GetFirstAsync(u => u.Id == input.Id)
            ?? throw Oops.Oh("题目不存在");
    }

    /// <summary>
    /// 获取题目管理列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取题目管理列表")]
    public async Task<List<EtQuestionOutput>> List([FromQuery] PageEtQuestionInput input)
    {
        return await _etQuestionRep.AsQueryable().Select<EtQuestionOutput>().ToListAsync();
    }


    /// <summary>
    /// 上传附件
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "UploadAttachments"), HttpPost]
    [DisplayName("上传附件")]
    public async Task<SysFile> UploadAttachments([Required] IFormFile file)
    {
            var service = App.GetRequiredService<SysFileService>();
            return await service.UploadFile(new FileUploadInput { File = file, Path = "upload/Attachments" }); 
    } 



}
